﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Principal;
using System.ComponentModel;
using System.Xml.Serialization;

namespace Apollo
{
    public class AsyncProcess
    {
        public AsyncProcess(string code, string name, BackgroundWorker worker, object workerArg, IIdentity owner) {
            this.StartDate = DateTime.Now;
            this.LastReportDate = DateTime.Now;
            this.ProgressPercentage = 0;

            this.Code = code;
            this.Name = name;

            if (owner != null) 
                this.Owner = owner;

            this.Worker = worker;
            this.Worker.WorkerReportsProgress = true;
            this.Worker.WorkerSupportsCancellation = true;
            this.Worker.ProgressChanged += new ProgressChangedEventHandler(Worker_ProgressChanged);
            this.Worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(Worker_RunWorkerCompleted);
            
            if(workerArg != null)
                this.Worker.RunWorkerAsync(workerArg);
            else
                this.Worker.RunWorkerAsync();
        }

        protected void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.ProgressPercentage = e.ProgressPercentage;
            this.LastReportDate = DateTime.Now;
        }

        protected void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            this.ProgressPercentage = 100;

            if (e.Cancelled) {
                this.Message = "Cancelled";
                this.MessageType = ActionMessageType.Warning;
            }

            if (e.Error != null) {
                this.Message = e.Error.Message;
                this.MessageType = ActionMessageType.Error;
            }

            if (e.Result != null && e.Result is string) {
                this.Message = (string)e.Result;
                this.MessageType = ActionMessageType.Info;
            }

            this.LastReportDate = DateTime.Now;
        }


        public DateTime StartDate { get; set; }
        public DateTime? EndDate { get; set; }
        public DateTime LastReportDate { get; set; }

        public string Code { get; set; }
        public string Name { get; set; }
        
        public string Message { get; set; }

        public ActionMessageType MessageType { get; set; }

        public int ProgressPercentage { get; set; }

        public IIdentity Owner { get; set; }

        public BackgroundWorker Worker { get; set; }



        public string ToJSON() {
            string message = this.Message;

            if (!string.IsNullOrEmpty(message))
                message = message.Replace("\\", "\\\\").Replace("\"", "\\\"");

            return @"
{ 
    ""StartDate"": """ + DateTimeHelper.ToUnixTime(this.StartDate).ToString() + @""",
    ""EndDate"": """ + (this.EndDate != null ? DateTimeHelper.ToUnixTime(this.EndDate.Value).ToString() : "") + @""",
    ""LastReportDate"": """ + DateTimeHelper.ToUnixTime(this.LastReportDate).ToString() + @""",

    ""Code"": """ + this.Code + @""",
    ""Name"": """ + this.Name + @""",

    ""Message"": """ + message + @""",
    ""MessageType"": """ + this.MessageType.ToString() + @"""
    ""ProgressPercentage"": """ + this.ProgressPercentage.ToString() + @"""
}
";
        }
    }
}
